﻿#pragma once
#include <Global.h>
class ServerPlayer;
struct DePlayerCB {
    void *userdata;
    void (*cb)(void *, ServerPlayer *);
    void operator()(ServerPlayer *sp) { cb(userdata, sp); }
};

LIAPI void _regDePlayerCB(DePlayerCB);

template <typename T>
class playerMap {
  public:
    std::unordered_map<ServerPlayer *, T> _map;

  private:
    static void onDelete(playerMap<T> &thi, ServerPlayer *sp) { thi._map.erase(sp); }

  public:
    playerMap() {
        DePlayerCB cb;
        cb.userdata = this;
        cb.cb       = (decltype(cb.cb))(&playerMap<T>::onDelete);
        _regDePlayerCB(cb);
    }
    inline T &get(ServerPlayer *sp) {
        auto it = _map.find(sp);
        if (it == _map.end()) {
            if constexpr (std::is_constructible<T, ServerPlayer &>()) {
                _map.emplace(sp, *sp);
            } else {
                _map.operator[](sp);
            }
            return get(sp);
        } else {
            return it->second;
        }
    }
    T &operator[](ServerPlayer *sp) { return get(sp); }
    T &operator[](ServerPlayer &sp) { return get(&sp); }
};